<template>
  <view class="chart-container">
    <canvas 
      class="chart-canvas" 
      :id="canvasId" 
      :canvas-id="canvasId"
      @touchstart="touchStart"
      @touchmove="touchMove"
      @touchend="touchEnd"
    ></canvas>
    
    <view v-if="showLegend" class="chart-legend">
      <view 
        v-for="(item, index) in legendData" 
        :key="index" 
        class="legend-item"
      >
        <view class="legend-color" :style="{ backgroundColor: item.color }"></view>
        <text class="legend-text">{{ item.name }}</text>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  name: 'Chart',
  props: {
    // 图表类型: line, bar, pie
    type: {
      type: String,
      default: 'line'
    },
    // 图表数据
    data: {
      type: Object,
      required: true
    },
    // 图表配置
    options: {
      type: Object,
      default: () => ({})
    },
    // 是否显示图例
    showLegend: {
      type: Boolean,
      default: true
    }
  },
  
  data() {
    return {
      canvasId: 'chartCanvas_' + Date.now(),
      ctx: null,
      legendData: [],
      touchInfo: {
        startX: 0,
        startY: 0
      }
    };
  },
  
  mounted() {
    this.initChart();
  },
  
  watch: {
    data: {
      handler() {
        this.drawChart();
      },
      deep: true
    }
  },
  
  methods: {
    initChart() {
      // 创建canvas上下文
      const query = uni.createSelectorQuery().in(this);
      query.select('#' + this.canvasId).fields({ node: true, size: true }).exec((res) => {
        if (res[0]) {
          const canvas = res[0].node;
          this.ctx = canvas.getContext('2d');
          
          // 设置canvas尺寸
          const dpr = uni.getSystemInfoSync().pixelRatio;
          canvas.width = res[0].width * dpr;
          canvas.height = res[0].height * dpr;
          this.ctx.scale(dpr, dpr);
          
          // 绘制图表
          this.drawChart();
        }
      });
    },
    
    drawChart() {
      if (!this.ctx || !this.data) return;
      
      // 清空画布
      const canvas = this.ctx.canvas;
      this.ctx.clearRect(0, 0, canvas.width, canvas.height);
      
      // 根据图表类型绘制
      switch (this.type) {
        case 'line':
          this.drawLineChart();
          break;
        case 'bar':
          this.drawBarChart();
          break;
        case 'pie':
          this.drawPieChart();
          break;
        default:
          this.drawLineChart();
      }
    },
    
    drawLineChart() {
      const { labels = [], datasets = [] } = this.data;
      const canvas = this.ctx.canvas;
      const width = canvas.width / (uni.getSystemInfoSync().pixelRatio || 1);
      const height = canvas.height / (uni.getSystemInfoSync().pixelRatio || 1);
      
      // 图表边距
      const padding = {
        top: 20,
        right: 20,
        bottom: 40,
        left: 50
      };
      
      // 绘制坐标轴
      this.ctx.beginPath();
      this.ctx.strokeStyle = '#e0e0e0';
      this.ctx.lineWidth = 1;
      
      // Y轴
      this.ctx.moveTo(padding.left, padding.top);
      this.ctx.lineTo(padding.left, height - padding.bottom);
      
      // X轴
      this.ctx.moveTo(padding.left, height - padding.bottom);
      this.ctx.lineTo(width - padding.right, height - padding.bottom);
      this.ctx.stroke();
      
      // 绘制标签
      this.ctx.fillStyle = '#666';
      this.ctx.font = '12px sans-serif';
      this.ctx.textAlign = 'center';
      
      // X轴标签
      const xStep = (width - padding.left - padding.right) / (labels.length - 1);
      labels.forEach((label, index) => {
        const x = padding.left + index * xStep;
        const y = height - padding.bottom + 20;
        this.ctx.fillText(label, x, y);
      });
      
      // 绘制数据线
      datasets.forEach((dataset, datasetIndex) => {
        const color = dataset.borderColor || `hsl(${datasetIndex * 60}, 70%, 50%)`;
        this.ctx.strokeStyle = color;
        this.ctx.lineWidth = 2;
        this.ctx.beginPath();
        
        const yMax = Math.max(...dataset.data);
        const yMin = Math.min(...dataset.data);
        const yRange = yMax - yMin || 1; // 避免除零
        
        dataset.data.forEach((value, index) => {
          const x = padding.left + index * xStep;
          const y = padding.top + (height - padding.top - padding.bottom) * (1 - (value - yMin) / yRange);
          
          if (index === 0) {
            this.ctx.moveTo(x, y);
          } else {
            this.ctx.lineTo(x, y);
          }
        });
        
        this.ctx.stroke();
        
        // 添加图例数据
        if (this.showLegend) {
          this.legendData.push({
            name: dataset.label,
            color: color
          });
        }
      });
    },
    
    drawBarChart() {
      const { labels = [], datasets = [] } = this.data;
      const canvas = this.ctx.canvas;
      const width = canvas.width / (uni.getSystemInfoSync().pixelRatio || 1);
      const height = canvas.height / (uni.getSystemInfoSync().pixelRatio || 1);
      
      // 图表边距
      const padding = {
        top: 20,
        right: 20,
        bottom: 40,
        left: 50
      };
      
      // 绘制坐标轴
      this.ctx.beginPath();
      this.ctx.strokeStyle = '#e0e0e0';
      this.ctx.lineWidth = 1;
      
      // Y轴
      this.ctx.moveTo(padding.left, padding.top);
      this.ctx.lineTo(padding.left, height - padding.bottom);
      
      // X轴
      this.ctx.moveTo(padding.left, height - padding.bottom);
      this.ctx.lineTo(width - padding.right, height - padding.bottom);
      this.ctx.stroke();
      
      // 绘制标签
      this.ctx.fillStyle = '#666';
      this.ctx.font = '12px sans-serif';
      this.ctx.textAlign = 'center';
      
      // X轴标签
      const barWidth = (width - padding.left - padding.right) / labels.length;
      labels.forEach((label, index) => {
        const x = padding.left + index * barWidth + barWidth / 2;
        const y = height - padding.bottom + 20;
        this.ctx.fillText(label, x, y);
      });
      
      // 绘制柱状图
      const barPadding = 10;
      datasets.forEach((dataset, datasetIndex) => {
        const color = dataset.backgroundColor || `hsl(${datasetIndex * 60}, 70%, 50%)`;
        this.ctx.fillStyle = color;
        
        const yMax = Math.max(...dataset.data);
        const yMin = Math.min(...dataset.data);
        const yRange = yMax - yMin || 1; // 避免除零
        
        dataset.data.forEach((value, index) => {
          const barHeight = (height - padding.top - padding.bottom) * (value - yMin) / yRange;
          const x = padding.left + index * barWidth + barPadding + (datasetIndex * (barWidth - barPadding * 2) / datasets.length);
          const y = height - padding.bottom - barHeight;
          const w = (barWidth - barPadding * 2) / datasets.length;
          const h = barHeight;
          
          this.ctx.fillRect(x, y, w, h);
        });
        
        // 添加图例数据
        if (this.showLegend) {
          this.legendData.push({
            name: dataset.label,
            color: color
          });
        }
      });
    },
    
    drawPieChart() {
      const { labels = [], datasets = [] } = this.data;
      const canvas = this.ctx.canvas;
      const width = canvas.width / (uni.getSystemInfoSync().pixelRatio || 1);
      const height = canvas.height / (uni.getSystemInfoSync().pixelRatio || 1);
      
      // 圆心和半径
      const centerX = width / 2;
      const centerY = height / 2;
      const radius = Math.min(width, height) / 2 - 20;
      
      // 计算总值
      const dataset = datasets[0] || { data: [] };
      const total = dataset.data.reduce((sum, value) => sum + value, 0);
      
      // 绘制饼图
      let startAngle = 0;
      dataset.data.forEach((value, index) => {
        const sliceAngle = (value / total) * 2 * Math.PI;
        const endAngle = startAngle + sliceAngle;
        
        const color = dataset.backgroundColor && dataset.backgroundColor[index] || `hsl(${index * 60}, 70%, 50%)`;
        this.ctx.fillStyle = color;
        
        // 绘制扇形
        this.ctx.beginPath();
        this.ctx.moveTo(centerX, centerY);
        this.ctx.arc(centerX, centerY, radius, startAngle, endAngle);
        this.ctx.closePath();
        this.ctx.fill();
        
        // 绘制标签线
        const midAngle = startAngle + sliceAngle / 2;
        const labelX = centerX + Math.cos(midAngle) * (radius + 10);
        const labelY = centerY + Math.sin(midAngle) * (radius + 10);
        
        this.ctx.beginPath();
        this.ctx.strokeStyle = '#666';
        this.ctx.lineWidth = 1;
        this.ctx.moveTo(centerX + Math.cos(midAngle) * radius, centerY + Math.sin(midAngle) * radius);
        this.ctx.lineTo(labelX, labelY);
        this.ctx.stroke();
        
        // 绘制标签文字
        this.ctx.fillStyle = '#666';
        this.ctx.font = '12px sans-serif';
        this.ctx.textAlign = 'center';
        this.ctx.fillText(labels[index], labelX, labelY + 15);
        
        startAngle = endAngle;
        
        // 添加图例数据
        if (this.showLegend) {
          this.legendData.push({
            name: labels[index],
            color: color
          });
        }
      });
    },
    
    touchStart(e) {
      const touch = e.touches[0];
      this.touchInfo.startX = touch.x;
      this.touchInfo.startY = touch.y;
      this.$emit('chart-touch-start', e);
    },
    
    touchMove(e) {
      this.$emit('chart-touch-move', e);
    },
    
    touchEnd(e) {
      this.$emit('chart-touch-end', e);
    }
  }
};
</script>

<style lang="scss" scoped>
.chart-container {
  width: 100%;
  height: 100%;
}

.chart-canvas {
  width: 100%;
  height: 300rpx;
}

.chart-legend {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  margin-top: $spacing-base;
}

.legend-item {
  display: flex;
  flex-direction: row;
  align-items: center;
  margin-right: $spacing-lg;
  margin-bottom: $spacing-sm;
}

.legend-color {
  width: 20rpx;
  height: 20rpx;
  border-radius: 10rpx;
  margin-right: $spacing-sm;
}

.legend-text {
  font-size: $font-size-sm;
  color: $text-primary;
}
</style>